package app.gui.control
{
	import app.util.*;
	import app.util.image.action.*;
	import app.util.image.calc.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	import mx.containers.*;
	import mx.controls.*;
	import mx.managers.*;
	
	public class ImageRepair
	{
		private var image:Canvas = null;
		private var currentAction:PartialProcessingAction;
		
		private var currentX:int;
		private var currentY:int;	
		private var radius:Number;	
		
		public var enablePreview:Boolean = false;
		public var enableBorder:Boolean = true;
		public var drawCircleBorder:Boolean = false;
		
		public function install(img:Canvas, action:PartialProcessingAction):void
		{
			this.image = img;
			this.currentAction = action;	
			this.currentX = this.currentY = int.MIN_VALUE;
			
			this.image.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.image.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			this.image.addEventListener(MouseEvent.ROLL_OUT, onMouseOut);
			
			this.drawCircle();	
		}

		public function uninstall():void
		{
			if(this.image != null)
			{
				this.image.graphics.clear();
				this.image.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				this.image.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				this.image.removeEventListener(MouseEvent.ROLL_OUT, onMouseOut);
				this.image = null;
			}
		}
		
		public function setValue(r:Number, s:Number):void
		{
			this.radius = r;
			this.currentAction.setStrength(s);
			
			this.drawCircle();
		}
		
		public function redraw():void
		{
			if(this.image != null)
			{
				this.putCenterTo(this.currentX, this.currentY);
				this.drawCircle();
			}
		}
		
		private function getRepairRegion():Array
		{
			//Returned array includes <x, y, r>
			if(this.image == null)
			{
				throw new Error("Not in repair-mode");
			}
			var scale:Number = Mediator.getCurrentImageConfig().scale;
			return [this.currentX / scale, this.currentY / scale, this.radius / scale];
		}
		
		private function drawCircle():void
		{	
			if(this.enableBorder && this.currentX != int.MIN_VALUE)
			{
				var g:Graphics = this.image.graphics;
				g.clear();
				g.lineStyle(2, 0, 1);
				if(this.drawCircleBorder)
				{
					g.drawCircle(this.currentX, this.currentY, this.radius);
				}
				else
				{
					g.drawRect(this.currentX - this.radius, this.currentY - this.radius, 2 * this.radius, 2 * this.radius);
				}
				g.endFill(); 
			}
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			this.currentAction.addPartial(this.getRepairRegion());
		}
		
		private function onMouseOut(e:MouseEvent):void
		{
			this.currentX = int.MIN_VALUE;
			this.image.graphics.clear();
			this.currentAction.previewPartial();
		}
		
		private function onMouseMove(e:MouseEvent):void
		{	
			if(this.enablePreview)
			{		
				this.currentAction.previewPartial(this.getRepairRegion());
			}
			this.putCenterTo(e.localX, e.localY);
			this.drawCircle();
		} 
		
		private function putCenterTo(x:Number, y:Number):void
		{
			if(x < this.radius) x = this.radius;
			if(x + this.radius > this.image.width) x = this.image.width - this.radius;
			if(y < this.radius) y = this.radius;
			if(y + this.radius > this.image.height) y = this.image.height - this.radius; 
			
			this.currentX = x;
			this.currentY = y;
		}
	}
}